/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, ref, SetupContext, watch } from 'vue';
import { paginationProps, PaginationPropsType } from './pagination.props';
import getGotoButton from './components/buttons/goto-buttons.component';
import getNextButtons from './components/buttons/next-buttons.component';
import getPageInfo from './components/pages/page-info.component';
import getPageList from './components/pages/page-list.component';
import getPageNumber from './components/pages/page-number.component';
import getPreviousButtons from './components/buttons/previous-buttons.component';
import { usePages } from './composition/use-pages';

import './pagination.css';

export default defineComponent({
    name: 'FPagination',
    props: paginationProps,
    emits: ['pageIndexChanged', 'pageSizeChanged'] as (string[] & ThisType<void>) | undefined,
    setup(props: PaginationPropsType, context: SetupContext) {
        const responsive = ref(false);
        const viewModel = ref(props.mode);
        const position = ref('');
        const autoHide = ref(false);
        const currentPageSize = ref(props.pageSize);
        const currentPage = ref(props.currentPage);
        const totalItems = ref(props.totalItems);

        const { pages, updatePages } = usePages(props);

        const isFirstPage = computed(() => {
            return currentPage.value === 1;
        });

        const pageList = computed(() => {
            return [20, 50, 100];
        });

        const lastPage = computed(() => {
            return Math.ceil(totalItems.value / currentPageSize.value);
        });

        const isLastPage = computed(() => {
            return currentPage.value === lastPage.value;
        });

        const shouldShowGoButton = computed(() => {
            return true;
        });

        const shouldShowFirstPageLink = computed(() => {
            return currentPage.value > 1;
        });

        const shouldShowNavigation = computed(() => {
            return !(autoHide.value && pages.value.length <= 1);
        });

        const shouldShowPageInfo = computed(() => {
            return true;
        });

        const shouldShowPageList = computed(() => {
            return true;
        });

        const shouldShowPageNumbers = computed(() => {
            return true;
        });

        const shouldShowRedirectionLinks = computed(() => {
            return true;
        });

        const { renderFirstPage, renderPreviousPage } = getPreviousButtons(currentPage, isFirstPage, shouldShowFirstPageLink);
        const { renderLastPage, renderNextPage } = getNextButtons(currentPage, isLastPage, lastPage);
        const { renderPageInfo } = getPageInfo(position, totalItems);
        const { renderPageList } = getPageList(currentPage, currentPageSize, pageList, totalItems);
        const { renderPageNumbers } = getPageNumber(currentPage, pages);
        const { renderGotoButton } = getGotoButton(currentPage, lastPage);

        updatePages(currentPage.value, currentPageSize.value, totalItems.value, 7);

        watch([currentPage, currentPageSize], () => {
            updatePages(currentPage.value, currentPageSize.value, totalItems.value, 7);
        });

        watch(currentPage, () => {
            context.emit('pageIndexChanged', currentPage.value);
        });

        watch(currentPageSize, () => {
            context.emit('pageSizeChanged', currentPageSize.value);
        });

        const paginationClass = computed(() => {
            const classObject = {
                'ngx-pagination': true,
                pagination: true,
                responsive: responsive.value,
                'pager-viewmode-default': viewModel.value === 'default',
                'pager-viewmode-simple': viewModel.value === 'simple'
            } as Record<string, boolean>;
            return classObject;
        });

        const paginationStyle = computed(() => {
            const styleObject = {
                position: 'relative',
                'justify-content': position.value === 'center' ? 'center' : 'start'
            } as Record<string, any>;
            return styleObject;
        });

        function renderDefaultPagination() {
            return (
                <>
                    {shouldShowPageInfo.value && renderPageInfo()}
                    {shouldShowPageList.value && renderPageList()}
                    {shouldShowRedirectionLinks.value && renderFirstPage()}
                    {shouldShowRedirectionLinks.value && renderPreviousPage()}
                    {shouldShowPageNumbers.value && renderPageNumbers()}
                    {shouldShowRedirectionLinks.value && renderNextPage()}
                    {shouldShowRedirectionLinks.value && renderLastPage()}
                    {shouldShowGoButton.value && renderGotoButton()}
                </>
            );
        }

        function renderSimplePagination() {
            return (
                <>
                    <li class="page-item d-flex flex-fill"></li>
                    {shouldShowRedirectionLinks.value && renderFirstPage()}
                    {shouldShowRedirectionLinks.value && renderPreviousPage()}
                    {renderGotoButton()}
                    <li class="page-item page-separator" style="margin-left: 10px">
                        <span style="font-size: 15px; font-weight: 200;"> /</span>
                    </li>
                    <li class="page-item page-total" style="margin-left: 5px">
                        <span style="font-size: 16px; font-weight: 600;"> {lastPage.value}</span>
                    </li>
                    {shouldShowRedirectionLinks.value && renderNextPage()}
                    {shouldShowRedirectionLinks.value && renderLastPage()}
                </>
            );
        }

        return () => {
            return (
                <div class="pagination-container">
                    {shouldShowNavigation.value && (
                        <ul role="navigation" class={paginationClass.value} style={paginationStyle.value}>
                            {viewModel.value === 'default' ? renderDefaultPagination() : renderSimplePagination()}
                        </ul>
                    )}
                </div>
            );
        };
    }
});
